package com.jm88.tools;

import java.io.File;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.output.FileWriterWithEncoding;
import org.apache.commons.lang.StringUtils;

import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
/**
 * 生成MAVEN ssi 项目.
 *
 * @author saber
 * @version Jan 8, 2011
 */
public class GenSSIMvnProject {
    private static String outputDir = "target/mvn";
    private static Configuration cfg = new Configuration();
    private static String groupId = "";
    static {
        // Specify the data source where the template files come from.
        // Here I set a file directory for it:
        cfg.setClassForTemplateLoading(GenSSIMvnProject.class, "/");
        // Specify how templates will see the data-model. This is an advanced
        // topic...
        // but just use this:
        cfg.setObjectWrapper(new DefaultObjectWrapper());
        cfg.setDefaultEncoding("utf-8");
    }

    public static void main(String[] args) throws Exception {
        File dir = new File(outputDir);
        if (dir.exists()) {
            FileUtils.deleteDirectory(dir);
        }
        dir.mkdirs();
        //TODO 使用时修改
        String pjName = "oa";
        groupId = "com.baoz";
        String artifactIdPrefix = pjName;
        
        genParentPom(artifactIdPrefix);
        genApiProject(artifactIdPrefix, groupId, artifactIdPrefix + "-api", groupId + ".api");
        genCoreProject(artifactIdPrefix, groupId, artifactIdPrefix + "-core", groupId);
        genWebProject(artifactIdPrefix, groupId, artifactIdPrefix + "-web", "web", groupId + ".web");
        genWebProject(artifactIdPrefix, groupId, artifactIdPrefix + "-admin", "admin", groupId + ".web");
        genEsbProject(artifactIdPrefix, groupId, artifactIdPrefix + "-esb", groupId + ".esb");
        genClientProject(artifactIdPrefix, groupId, artifactIdPrefix + "-client", groupId + ".client");
    }

    private static void genParentPom(String artifactIdPrefix) throws Exception {
        Map<Object, Object> root = new HashMap<Object, Object>();
        root.put("artifactIdPrefix", artifactIdPrefix);
        root.put("groupId", groupId);
        genFile(cfg.getTemplate("template/mvn/parent-pom.ftl"),root,new File(outputDir, "pom.xml"));
    }

    private static void genApiProject(String artifactIdPrefix, String groupId, String artifactId, String packageName)
            throws Exception {
        File dir = new File(outputDir);
        File pjFile = new File(dir, artifactId);
        // 创建目录
        File javadir = new File(pjFile, "src/main/java");
        javadir.mkdirs();
        File javaResdir = new File(pjFile, "src/main/resources");
        javaResdir.mkdirs();
        File javaSpingsdir = new File(pjFile, "src/main/resources/spring");
        javaSpingsdir.mkdirs();
        File javaPackage = new File(javadir, StringUtils.replace(packageName, ".", "/"));
        javaPackage.mkdirs();
        // /////////////////
        File testdir = new File(pjFile, "src/test/java");
        testdir.mkdirs();
        File testResdir = new File(pjFile, "src/test/resources");
        testResdir.mkdirs();
        // ////////////////
        // 标准目录
        new File(javaPackage, "constant").mkdirs();
        new File(javaPackage, "util").mkdirs();
        new File(javaPackage, "vo").mkdirs();
        // 生成pom
        Map<Object, Object> root = new HashMap<Object, Object>();
        root.put("groupId", groupId);
        root.put("artifactIdPrefix", artifactIdPrefix);
        root.put("artifactId", artifactId);
        genFile(cfg.getTemplate("template/mvn/api/pom.ftl"),root,new File(outputDir, artifactId + "/pom.xml"));
    }

    private static void genCoreProject(String artifactIdPrefix, String groupId, String artifactId, String packageName)
            throws Exception {
        File dir = new File(outputDir);
        File pjFile = new File(dir, artifactId);
        // 创建目录
        File javadir = new File(pjFile, "src/main/java");
        javadir.mkdirs();
        File javaResdir = new File(pjFile, "src/main/resources");
        javaResdir.mkdirs();
        File javaSpingsdir = new File(pjFile, "src/main/resources/spring");
        javaSpingsdir.mkdirs();
        File javaIbatisdir = new File(pjFile, "src/main/resources/ibatis");
        javaIbatisdir.mkdirs();
        File javaPackage = new File(javadir, StringUtils.replace(packageName, ".", "/"));
        javaPackage.mkdirs();
        // /////////////////
        File testdir = new File(pjFile, "src/test/java");
        testdir.mkdirs();
        File testResdir = new File(pjFile, "src/test/resources");
        testResdir.mkdirs();
        File testSpingsdir = new File(pjFile, "src/test/resources/spring");
        testSpingsdir.mkdirs();
        File testPackage = new File(testdir, StringUtils.replace(packageName, ".", "/"));
        testPackage.mkdirs();
        // 标准目录
        new File(javaPackage, "api/impl").mkdirs();
        new File(javaPackage, "constant").mkdirs();
        new File(javaPackage, "util").mkdirs();
        new File(javaPackage, "vo").mkdirs();
        new File(javaPackage, "model").mkdirs();
        new File(javaPackage, "dao").mkdirs();
        File daoImplDir = new File(javaPackage, "dao/impl");
        daoImplDir.mkdirs();
        new File(javaPackage, "manager").mkdirs();
        new File(javaPackage, "manager/impl").mkdirs();
        ///////////
        File daoImplTestDir = new File(testPackage, "dao/impl");
        daoImplTestDir.mkdirs();
        File managerImplTestDir = new File(testPackage, "manager/impl");
        managerImplTestDir.mkdirs();
        // 生成pom
        Map<Object, Object> root = new HashMap<Object, Object>();
        root.put("groupId", groupId);
        root.put("artifactIdPrefix", artifactIdPrefix);
        root.put("artifactId", artifactId);
        genFile(cfg.getTemplate("template/mvn/core/pom.ftl"),root,new File(outputDir, artifactId + "/pom.xml"));
        // 生成java的spring样例文件
        genFile(cfg.getTemplate("template/mvn/core/applicationContext-aop.ftl"),root,new File(javaSpingsdir, "applicationContext-aop.xml"));
        genFile(cfg.getTemplate("template/mvn/core/applicationContext-api.ftl"),root,new File(javaSpingsdir, "applicationContext-api.xml"));
        genFile(cfg.getTemplate("template/mvn/core/applicationContext-dao.ftl"),root,new File(javaSpingsdir, "applicationContext-dao.xml"));
        genFile(cfg.getTemplate("template/mvn/core/applicationContext-manager.ftl"),root,new File(javaSpingsdir, "applicationContext-manager.xml"));
        genFile(cfg.getTemplate("template/mvn/core/applicationContext-service.ftl"),root,new File(javaSpingsdir, "applicationContext-service.xml"));
        // 生成java的ibatis样例文件
        genFile(cfg.getTemplate("template/mvn/core/sql-map-config.ftl"),root,new File(javaIbatisdir, "sql-map-config.xml"));
        // 生成dao基类
        genFile(cfg.getTemplate("template/mvn/core/AbstractBaseDao.ftl"),root,new File(daoImplDir, "AbstractBaseDao.java"));
        // 生成dao的junit样例
        genFile(cfg.getTemplate("template/mvn/core/SampleDaoImplTest.ftl"),root,new File(daoImplTestDir, "SampleDaoImplTest.java"));
        // 生成manager的junit样例
        genFile(cfg.getTemplate("template/mvn/core/SampleManagerTest.ftl"),root,new File(managerImplTestDir, "SampleManagerTest.java"));
        // 生成test的spring样例文件
        genFile(cfg.getTemplate("template/mvn/core/applicationContext-test.ftl"),root,new File(testSpingsdir, "applicationContext-test.xml"));
        // 生成test的logback样例文件
        genFile(cfg.getTemplate("template/mvn/core/test-logback.ftl"),root,new File(testResdir, "logback.xml"));
        // 生成test的辅助类
        genFile(cfg.getTemplate("template/mvn/core/JndiMockUtils.ftl"),root,new File(testPackage, "JndiMockUtils.java"));
        genFile(cfg.getTemplate("template/mvn/core/MockJndiContext.ftl"),root,new File(testPackage, "MockJndiContext.java"));
    }

    private static void genWebProject(String artifactIdPrefix, String groupId, String artifactId, String moduleName,
            String packageName) throws Exception {
        File dir = new File(outputDir);
        File pjFile = new File(dir, artifactId);
        // 创建目录
        File javadir = new File(pjFile, "src/main/java");
        javadir.mkdirs();
        File javaResdir = new File(pjFile, "src/main/resources");
        javaResdir.mkdirs();
        File javaSpingsdir = new File(pjFile, "src/main/resources/spring");
        javaSpingsdir.mkdirs();
        File webdir = new File(pjFile, "src/main/webapp");
        webdir.mkdirs();
        File webInfdir = new File(pjFile, "src/main/webapp/WEB-INF");
        webInfdir.mkdirs();
        File metaInfdir = new File(pjFile, "src/main/webapp/META-INF");
        metaInfdir.mkdirs();
        File macrofdir = new File(pjFile, "src/main/webapp/WEB-INF/ftl/macro");
        macrofdir.mkdirs();
        File javaPackage = new File(javadir, StringUtils.replace(packageName, ".", "/"));
        javaPackage.mkdirs();
        // /////////////////
        File testdir = new File(pjFile, "src/test/java");
        testdir.mkdirs();
        File testResdir = new File(pjFile, "src/test/resources");
        testResdir.mkdirs();
        // 标准目录
        new File(javaPackage, "constant").mkdirs();
        new File(javaPackage, "util").mkdirs();
        new File(javaPackage, "vo").mkdirs();
        File javaControllerDir = new File(javaPackage, "controller");
        javaControllerDir.mkdirs();
        // 生成pom
        Map<Object, Object> root = new HashMap<Object, Object>();
        root.put("groupId", groupId);
        root.put("artifactIdPrefix", artifactIdPrefix);
        root.put("artifactId", artifactId);
        root.put("moduleName", moduleName);
        genFile(cfg.getTemplate("template/mvn/web/pom.ftl"),root,new File(outputDir, artifactId + "/pom.xml"));
        // 生成context.xml
        FileUtils.copyFileToDirectory(new File("src/main/resources/template/mvn/web/context.xml"), metaInfdir);
        // 生成web.xml
        FileUtils.copyFileToDirectory(new File("src/main/resources/template/mvn/web/web.xml"), webInfdir);
        // layout
        FileUtils.copyFileToDirectory(new File("src/main/resources/template/mvn/web/layout.ftl"), macrofdir);
        // resources
        FileUtils.copyFileToDirectory(new File("src/main/resources/template/mvn/web/freemarker.properties"), javaResdir);
        FileUtils.copyFileToDirectory(new File("src/main/resources/template/mvn/web/logback.xml"), javaResdir);
        FileUtils.copyFileToDirectory(new File("src/main/resources/template/mvn/web/struts.xml"), javaResdir);
        FileUtils.copyFileToDirectory(new File("src/main/resources/template/mvn/web/xwork-conversion.properties"), javaResdir);
        genFile(cfg.getTemplate("template/mvn/web/struts.properties.ftl"),root,new File(javaResdir, "struts.properties"));
        // spring文件
        FileUtils.copyFileToDirectory(new File("src/main/resources/template/mvn/web/applicationContext-web.xml"), javaSpingsdir);
        // java
        genFile(cfg.getTemplate("template/mvn/web/abstractBaseController.ftl"),root,new File(javaControllerDir, "AbstractBaseController.java"));
        // error page
        FileUtils.copyDirectoryToDirectory(new File("src/main/resources/template/mvn/web/jsp"), webInfdir);
    }

    private static void genEsbProject(String artifactIdPrefix, String groupId, String artifactId, String packageName)
            throws Exception {
        File dir = new File(outputDir);
        File pjFile = new File(dir, artifactId);

        // 创建目录
        File javadir = new File(pjFile, "src/main/java");
        javadir.mkdirs();
        File javaResdir = new File(pjFile, "src/main/resources");
        javaResdir.mkdirs();
        // /////////////////
        File testdir = new File(pjFile, "src/test/java");
        testdir.mkdirs();
        File testResdir = new File(pjFile, "src/test/resources");
        testResdir.mkdirs();
        // ////////////////
        File webdir = new File(pjFile, "src/main/webapp");
        webdir.mkdirs();
        File webInfdir = new File(pjFile, "src/main/webapp/WEB-INF");
        webInfdir.mkdirs();
        File metaInfdir = new File(pjFile, "src/main/webapp/META-INF");
        metaInfdir.mkdirs();

        File javaPackage = new File(javadir, StringUtils.replace(packageName, ".", "/"));
        javaPackage.mkdirs();
        // 生成pom
        Map<Object, Object> root = new HashMap<Object, Object>();
        root.put("groupId", groupId);
        root.put("artifactIdPrefix", artifactIdPrefix);
        root.put("artifactId", artifactId);
        genFile(cfg.getTemplate("template/mvn/esb/pom.ftl"),root,new File(outputDir, artifactId + "/pom.xml"));
        // 生成context.xml
        FileUtils.copyFileToDirectory(new File("src/main/resources/template/mvn/esb/context.xml"), metaInfdir);
        // 生成web.xml
        FileUtils.copyFileToDirectory(new File("src/main/resources/template/mvn/esb/web.xml"), webInfdir);
        // 生成service-servlet.xml
        FileUtils.copyFileToDirectory(new File("src/main/resources/template/mvn/esb/service-servlet.xml"), webInfdir);
        // logback 
        FileUtils.copyFileToDirectory(new File("src/main/resources/template/mvn/esb/logback.xml"), javaResdir);
    }

    private static void genClientProject(String artifactIdPrefix, String groupId, String artifactId, String packageName)
            throws Exception {
        File dir = new File(outputDir);
        File pjFile = new File(dir, artifactId);
        // 创建目录
        File javadir = new File(pjFile, "src/main/java");
        javadir.mkdirs();
        File javaResdir = new File(pjFile, "src/main/resources");
        javaResdir.mkdirs();
        File javaSpingsdir = new File(pjFile, "src/main/resources/service");
        javaSpingsdir.mkdirs();
        File javaPackage = new File(javadir, StringUtils.replace(packageName, ".", "/"));
        javaPackage.mkdirs();
        // ////
        File testdir = new File(pjFile, "src/test/java");
        testdir.mkdirs();
        File testResdir = new File(pjFile, "src/test/resources");
        testResdir.mkdirs();
        File testSpingsdir = new File(pjFile, "src/test/resources/service");
        testSpingsdir.mkdirs();
        // 标准目录
        new File(javaPackage, "constant").mkdirs();
        new File(javaPackage, "util").mkdirs();
        new File(javaPackage, "vo").mkdirs();
        // 生成pom
        Map<Object, Object> root = new HashMap<Object, Object>();
        root.put("groupId", groupId);
        root.put("artifactIdPrefix", artifactIdPrefix);
        root.put("artifactId", artifactId);
        genFile(cfg.getTemplate("template/mvn/client/pom.ftl"),root,new File(outputDir, artifactId + "/pom.xml"));
    }

    private static void genFile(Template template, Map<Object, Object> root, File f) throws Exception {
        Writer wirter = new FileWriterWithEncoding(f, "utf-8");
        template.process(root, wirter);
        wirter.close();
    }
}
